# -*- coding: utf-8 -*-

"""
=============================
this is a feibot product,
all rights reserved.
www.feibot.com
@author: Gu Tianyuan
@email: g@feibot.com
@time: ${DATE}:${TIME}
@product: ${PRODUCT_NAME}
=============================
"""
import datetime
import math
import shutil
import time
import os
import subprocess

import psutil

from gtyConfig import systemConfig


def getTimeStamp(year, month, day, hour, minute, second, centiSecond):
    # dt为字符串
    if int(year) < 2000:
        year = int(year) + 2000
    dt = '%d-%d-%d %d:%d:%d' % (year, month, day, hour, minute, second)
    # 中间过程，一般都需要将字符串转化为时间数组
    time.strptime(dt, '%Y-%m-%d %H:%M:%S')
    # 将"2012-03-28 06:53:40"转化为时间戳
    s = time.mktime(time.strptime(dt, '%Y-%m-%d %H:%M:%S'))
    return int(s) + centiSecond


# 电池曲线
def batteryPercentage(v, hardwareType):
    if hardwareType == 'A400':
        if v >= 12.2:
            return 100
        elif v > 11.5:
            return (v - 11.5) * 35.82 + 75
        elif v > 11:
            return (v - 11) * 50 + 50
        elif v > 10.6:
            return (v - 10.6) * 62.5 + 25
        elif v > 9.5:
            return (v - 9.5) * 22.73
        else:
            return 0
    else:
        if v >= 12.2:
            return 100
        elif v > 11.1:
            return (v - 11.1) * 20.8 + 75
        elif v > 10.6:
            return (v - 10.6) * 50 + 50
        elif v > 10.1:
            return (v - 10.1) * 50 + 25
        elif v > 8.7:
            return (v - 8.7) * 17.86
        else:
            return 0


# 获取ip地址
def getIpAddr():
    try:
        cmd = 'ifconfig | grep \"inet \" | awk \'{ print $2}\''
        p = os.popen(cmd)
        res = p.read()
        a = res.split('\n')
        infos = []
        for i in a:
            if len(i) >= 2:
                if '127.0.0.1' not in i:
                    infos.append(i)
        return infos
    except Exception as e:
        print(e)
        return []


def check_ip(ipaddr):
    addr = str(ipaddr).strip().split('.')  # 切割IP地址为一个列表

    if len(addr) != 4:  # 切割后列表必须有4个参数
        return False

    for i in range(4):
        try:
            addr[i] = int(addr[i])  # 每个参数必须为数字，否则校验失败
        except Exception as e:
            print(e)
            return False

        if 255 >= addr[i] >= 0:  # 每个参数值必须在0-255之间
            pass
        else:
            return False

    return True


# 检查当前已经运行的进程个数，避免重复启动
def checkAlreadyRun():
    # 防止重复启动
    pids = psutil.pids()
    count = 0
    for pid in pids:
        try:
            p = psutil.Process(pid)
            cmdList = p.cmdline()
            if len(cmdList) > 1 and "platformStart.py" in cmdList[1]:
                count += 1
        except psutil.ZombieProcess:  # 僵尸进程跳过否则报错
            pass
        except psutil.NoSuchProcess:
            pass
        except psutil.AccessDenied:
            pass
    return count


# 读取本地的ip，mask，gateway
def GetNetworkInfo():
    try:
        import netifaces
        Networkdict = {}

        routingGateway = netifaces.gateways()[2][0][0]  # 网关
        # print __file__,'interface:',netifaces.interfaces()

        interface = getInterfaces()
        # try:
        routingIPAddr = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['addr']  # 获取IP
        routingMusk = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['netmask']
        # except KeyError:
        # pass
        Networkdict['Interface'] = interface
        Networkdict['IP'] = routingIPAddr
        Networkdict['MASK'] = routingMusk
        Networkdict['GATEWAYS'] = routingGateway
        return Networkdict
    except:
        try:
            interface = 'wlan0'
            # try:
            routingIPAddr = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['addr']  # 获取IP
            routingMusk = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['netmask']
            # except KeyError:
            # pass
            Networkdict['Interface'] = interface
            Networkdict['IP'] = routingIPAddr
            Networkdict['MASK'] = routingMusk
            if '172' in routingIPAddr:
                routingGateway = ''
            Networkdict['GATEWAYS'] = routingGateway
            return Networkdict
        except:
            return 'failed'


# 从列表中获取需要的网卡号，如果有有线链接，那么返回有线链接。如果没有有线链接，返回无线链接。
def getInterfaces():
    try:
        import netifaces
        interfaceList = netifaces.interfaces()
        for i in interfaceList:
            if i != 'wlan0' and len(i) >= 4:  # 此处改为4 有可能使用网线导致eth0无法识别
                return i
        return 'wlan0'
    except:
        return 'wlan0'


# T400用
macList = {
    "48:8F:4C:DF:05:B4": "T001",
    "3C:6D:66:03:7F:B1": "T001",
    "3C:6D:66:11:83:A1": "T003",
    "3C:6D:66:11:84:93": "T004",
    "3C:6D:66:11:84:6D": "T005",
    "3C:6D:66:0D:5D:21": "T006",
    "3C:6D:66:11:84:8E": "T007",
    "3C:6D:66:11:83:90": "T008",
    "3C:6D:66:11:83:8E": "T009",
    "3C:6D:66:11:84:5F": "T010",
    "3C:6D:66:11:84:64": "T100",  # 串口测试机
}


def getMachineId(string='8b7e9c0dcc'):
    try:
        with open("/proc/device-tree/model", "r") as f:
            cpuinfo = f.read().lower()
        if 'jetson' in cpuinfo:
            from getmac import get_mac_address
            mac = get_mac_address(interface='eth0').upper()
            machineId = macList[mac]
        else:
            import compiled
            machineId = compiled.getMachineId(string)
    except FileNotFoundError:
        pass
    return machineId


def linuxSudoCmd(cmd):
    password = systemConfig.passwd
    full_cmd = f"echo {password} | sudo -S {cmd}"
    try:
        result = subprocess.run(full_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        if result.returncode != 0:
            raise Exception(result.stderr.strip())
        return result.stdout.strip()
    except Exception as e:
        print(f"Command failed: {cmd}\nError: {e}")
        raise e


# 由时间戳返回年月日时分秒，如果规则不符合，则返回错误，返回值为
# 格式为%02/04d-%02d-%02d %d:%d:%d.%d，日期和时间之间的间隔推荐为_，也可以为空格
# 同时兼容日期和时间中间为T，最后有Z的格式
def buildDateTime(timeDateString, direction=-1):
    try:
        s = timeDateString.upper()
        s = s.replace('Z', '')
        s = s.replace('T', '-')
        s = s.replace(' ', '-')
        s = s.replace('_', '-')
        s = s.replace(':', '-')
        parts = s.split('-')
        if len(parts) != 6:
            return False, 1
        year = int(parts[0])
        month = int(parts[1])
        day = int(parts[2])
        hour = int(parts[3])
        minute = int((parts[4]))
        if direction == -1:
            second = math.floor(float(parts[5]))
        else:
            second = math.ceil(float(parts[5]))
        if year < 100:
            year += 2000
        res = datetime.datetime.strptime("%4d-%d-%d %d:%d:%d" % (year, month, day, hour, minute, second),
                                         "%Y-%m-%d %H:%M:%S")
        return True, res
    except Exception as e:
        print(e)
        return False, 2
        pass


# 字节转16进制数字
def getHex(i):
    if i in '1234567890':
        return int(i)
    if i in 'aA':
        return 10
    if i in 'bB':
        return 11
    if i in 'cC':
        return 12
    if i in 'dD':
        return 13
    if i in 'eE':
        return 14
    if i in 'fF':
        return 15


# 按用户需求重新格式化epc
def epcReformat(tag, formatCmd,ShowfilteredtagsEnable=0,sendEventFunc=None):
    def show_not_allowed():
        if ShowfilteredtagsEnable and sendEventFunc is not None:
            sendEventFunc('UI', 'ui_showNotAllowedEpc', tag)

    epc1 = tag.epcString
    if formatCmd is None or formatCmd in ["RaceTec", "format5", "format2"]:
        return epc1
    # 客户Albert
    if formatCmd == 'format6':
        if epc1.startswith("0057") and len(epc1) >= 8:
            s = getHex(epc1[-1]) + getHex(epc1[-2]) * 16 + getHex(epc1[-3]) * 256 + getHex(epc1[-4]) * 256 * 16
            return str(s)
        else:
            show_not_allowed()
            return ""
    # 客户Carlos
    if formatCmd == 'format7':
        if epc1.startswith("11110000000000000") and len(epc1) >= 24:
            return str(epc1[-6:])
        else:
            show_not_allowed()
            return ""
    if formatCmd == 'test1':  # 客户标签是十进制 8位只保留开头的‘20’，后面都可能是会使用的标签
        if epc1.startswith("20") and len(epc1) >= 8:
            s = getHex(epc1[-1]) + getHex(epc1[-2]) * 10 + getHex(epc1[-3]) * 100 + getHex(epc1[-4]) * 1000 + getHex(
                epc1[-5]) * 10000 + getHex(epc1[-6]) * 100000
            return str(s)
        else:
            show_not_allowed()
            return ""
    # 客户Koji
    if formatCmd == 'format4':
        if len(epc1) >= 24:
            return epc1
        else:
            show_not_allowed()
            return ""
    #  客户Macsha ascii转换
    if formatCmd == 'format1':
        if epc1.startswith("30"):
            split_chars = [epc1[i:i + 2] for i in range(0, len(epc1), 2)]
            ascii_chars = ''.join(chr(int(c, 16)) for c in split_chars)
            return ascii_chars.lstrip('0')
        else:
            show_not_allowed()
            return ""
    # 罗马尼亚客户读取24位标签将后8位转换为10进制
    if formatCmd in['format3', 'format8']:
        if len(epc1) >= 24:
            s = getHex(epc1[-1]) + getHex(epc1[-2]) * 16 + getHex(epc1[-3]) * 256 + getHex(epc1[-4]) * 256 * 16 + getHex(
                epc1[-5]) \
                * 256 * 256 + getHex(epc1[-6]) * 256 * 256 * 16 + getHex(epc1[-7]) * 256 * 256 * 256 + getHex(
                epc1[-8]) * 256 * 256 * 256 * 16
            return str(s)
        else:
            show_not_allowed()
            return ""


# 按用户需求重新格式化日期时间字符串
def dateTimeReformat(dateTimeString, formatCmd):
    if formatCmd == "blank space":
        return dateTimeString.replace('_', ' ')
    if formatCmd == "T":
        return dateTimeString.replace('_', 'T') + 'Z'
    return dateTimeString
